﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.OfficeArt
{
    internal class OfficeArtRGFOPTE
    {
        private readonly List<OfficeArtFOPTE> _rgfopte = new List<OfficeArtFOPTE>();
        private byte[] garbage;

        public int ByteLength
        {
            get
            {
                var result = Enumerable.Sum(_rgfopte, item => item.ByteLength);
                if (garbage != null)
                    result += garbage.Length;
                return result;
            }
        }

        public ushort Count
        {
            get { return (ushort)_rgfopte.Count; }
        }

        public void Read(BinaryReader reader, int count, uint byteLength)
        {
            var position = reader.BaseStream.Position;
            for (int i = 0; i < count; i++)
            {
                var item = new OfficeArtFOPTE();
                item.Read(reader);
                _rgfopte.Add(item);
            }
            foreach (OfficeArtFOPTE item in _rgfopte)
            {
                item.ReadComplexPart(reader);
            }
            var diff = byteLength - (reader.BaseStream.Position - position);
            if (diff >= 0)
                this.garbage = reader.ReadBytes((int)diff);
#if DEBUG
            Contract.Assert(reader.BaseStream.Position - position == byteLength);
#endif

        }

        public void Write(BinaryWriter writer)
        {
            foreach (OfficeArtFOPTE item in _rgfopte)
                item.Write(writer);
            foreach (OfficeArtFOPTE item in _rgfopte)
                item.WriteComplexPart(writer);
            if (garbage != null)
                writer.Write(garbage);
        }


        private void Read(BinaryReader reader, OfficeArtRecordHeader rh)
        {
            Read(reader, rh.recInstance, rh.recLen);
        }

#if DEBUG
        void Trace()
        {
            foreach (var item in this._rgfopte)
                Debug.WriteLine(item.OpId + " " + item.GetValue());
        }
#endif
        public int? GetOptionalIntegerProperty(OpId id)
        {
            foreach (var item in this._rgfopte)
            {
                if (item.OpId == id)
                {
                    return item.GetIntValue();
                }
            }
            return null;
        }

        public void AddProperty(OfficeArtFOPTE property)
        {
            _rgfopte.Add(property);
        }

        public string GetOptionalStringProperty(OpId id)
        {
            foreach (var item in this._rgfopte)
            {
                if (item.OpId == id)
                {
                    return item.GetStringValue();
                }
            }
            return null;
        }

        public object GetOptionalProperty(OpId id)
        {
            foreach (var item in this._rgfopte)
            {
                if (item.OpId == id)
                    return item.GetValue();
            }
            return null;
        }
    }
}